package co.yixiang.modules.shop.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import co.yixiang.modules.shop.domain.YxStoreProductAttrResult;
import co.yixiang.modules.shop.domain.YxStoreProductAttrValue;
import co.yixiang.modules.shop.domain.YxStorePromote;
import co.yixiang.modules.shop.domain.YxStorePromoteProduct;
import co.yixiang.modules.shop.repository.*;
import co.yixiang.modules.shop.service.YxStoreProductService;
import co.yixiang.modules.shop.service.YxStorePromoteService;
import co.yixiang.modules.shop.service.dto.ProductFormatDTO;
import co.yixiang.modules.shop.service.dto.YxStorePromoteDto;
import co.yixiang.modules.shop.service.dto.YxStorePromoteQueryCriteria;
import co.yixiang.modules.shop.service.mapper.YxStorePromoteMapper;
import co.yixiang.utils.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author frq
 * @date 2020-08-05
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxStorePromoteServiceImpl implements YxStorePromoteService {
    @Autowired
    private YxStorePromoteRepository yxStorePromoteRepository;
    @Autowired
    private YxStorePromoteMapper yxStorePromoteMapper;
    @Autowired
    private YxStoreProductRepository yxStoreProductRepository;
    @Autowired
    private YxStoreProductAttrRepository yxStoreProductAttrRepository;
    @Autowired
    private YxStoreProductAttrValueRepository yxStoreProductAttrValueRepository;
    @Autowired
    private YxStoreProductAttrResultRepository yxStoreProductAttrResultRepository;
    @Autowired
    private YxStoreProductService yxStoreProductService;

    @Autowired
    private YxStorePromoteProductRepository yxStorePromoteProductRepository;

    @Override
    public Map<String, Object> queryAll(YxStorePromoteQueryCriteria criteria, Pageable pageable) {
        Page<YxStorePromote> page = yxStorePromoteRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(yxStorePromoteMapper::toDto));
    }

    @Override
    public List<YxStorePromoteDto> queryAll(YxStorePromoteQueryCriteria criteria) {
        return yxStorePromoteMapper.toDto(yxStorePromoteRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    public YxStorePromoteDto findById(Integer id) {
        YxStorePromote yxStorePromoteProduct = yxStorePromoteRepository.findById(id).orElseGet(YxStorePromote::new);
        ValidationUtil.isNull(yxStorePromoteProduct.getId(), "YxStorePromoteProduct", "id", id);
        return yxStorePromoteMapper.toDto(yxStorePromoteProduct);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public YxStorePromoteDto create(YxStorePromoteDto resources) {
        YxStorePromote yxStorePromote = yxStorePromoteMapper.toEntity(resources);
        //活动中包含商品
        JSONArray array = JSON.parseArray(resources.getSalesPromotion());
        yxStorePromote.setIsDel(0);
        //商品数量
        yxStorePromote.setProductCount(array.size());
        yxStorePromote.setAddTime(new Date());
        yxStorePromote.setAdder(SecurityUtils.getUsername());
        YxStorePromoteDto storePromoteDto = yxStorePromoteMapper.toDto(yxStorePromoteRepository.save(yxStorePromote));
        for (int i = 0; array.size() > i; i++) {
            JSONObject obj = array.getJSONObject(i);
            Integer productId = obj.getInteger("id");
            //促销价
            BigDecimal promotePrice = obj.getBigDecimal("promotePrice");
            yxStoreProductRepository.updatePromotePrice(productId, promotePrice,resources.getBeginTime(),resources.getEndTime());
            //修改商品属性
            YxStoreProductAttrResult yxStoreProductAttrResult = yxStoreProductAttrResultRepository
                    .findByProductId(productId);
            //修改商品中的促销价
            if (ObjectUtil.isNotNull(yxStoreProductAttrResult)) {
                String jsonStr = yxStoreProductAttrResult.getResult();
                JSONObject jsonObject = JSON.parseObject(jsonStr);

                List<ProductFormatDTO> valueList = JSON.parseArray(
                        jsonObject.get("value").toString(), ProductFormatDTO.class);
                if (valueList != null && valueList.size() > 0) {
                    List<YxStoreProductAttrValue> valueGroup = new ArrayList<>();
                    List<ProductFormatDTO> newListFormatDTO = new ArrayList<>();
                    for (ProductFormatDTO productFormatDTO : valueList) {
                        YxStoreProductAttrValue yxStoreProductAttrValue = new YxStoreProductAttrValue();
                        yxStoreProductAttrValue.setProductId(productId);
                        List<String> stringList = productFormatDTO.getDetail().values()
                                .stream().collect(Collectors.toList());
                        Collections.sort(stringList);
                        yxStoreProductAttrValue.setSuk(StrUtil.
                                join(",", stringList));
                        yxStoreProductAttrValue.setPrice(BigDecimal.valueOf(productFormatDTO.getPrice() != null ? productFormatDTO.getPrice() : 0));
                        yxStoreProductAttrValue.setCost(BigDecimal.valueOf(productFormatDTO.getCost() != null ? productFormatDTO.getCost() : 0));
                        //重新调整库存
                        yxStoreProductAttrValue.setStock(productFormatDTO.getSales());
                        yxStoreProductAttrValue.setUnique(IdUtil.simpleUUID());
                        yxStoreProductAttrValue.setImage(productFormatDTO.getPic());
                        yxStoreProductAttrValue.setBarCode(productFormatDTO.getBarCode());
                        yxStoreProductAttrValue.setPleased(BigDecimal.valueOf(productFormatDTO.getPleased() != null ? productFormatDTO.getPleased() : 0));
                        yxStoreProductAttrValue.setPromotePrice(promotePrice);
                        valueGroup.add(yxStoreProductAttrValue);

                        //重新调整促销价
                        productFormatDTO.setPromotePrice(promotePrice.doubleValue());
                        newListFormatDTO.add(productFormatDTO);
                    }
                    //插入之前清空
                    yxStoreProductAttrValueRepository.deleteByProductId(productId);
                    //保存值
                    yxStoreProductAttrValueRepository.saveAll(valueGroup);


                    Map<String, Object> map = new LinkedHashMap<>();
                    map.put("attr", jsonObject.get("attr"));
                    map.put("value", newListFormatDTO);

                    //保存结果
                    yxStoreProductService.setResult(map, productId);
                }
            }
            YxStorePromoteProduct promoteProduct = new YxStorePromoteProduct();
            promoteProduct.setProductId(productId);
            promoteProduct.setPromoteId(storePromoteDto.getId());
            promoteProduct.setAddTime(new Date());
            yxStorePromoteProductRepository.save(promoteProduct);
        }
        return storePromoteDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(YxStorePromote resources) {
        YxStorePromote yxStorePromote = yxStorePromoteRepository.findById(resources.getId()).orElseGet(YxStorePromote::new);
        ValidationUtil.isNull(yxStorePromote.getId(), "YxStorePromote", "id", resources.getId());
        yxStorePromote.copy(resources);
        yxStorePromoteRepository.save(yxStorePromote);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            yxStorePromoteRepository.deleteById(id);
            yxStorePromoteRepository.deletePromoteId(id);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void onSale(Integer id, Integer status) {
        if (status == 1) {
            status = 0;
        } else {
            status = 1;
        }
        yxStorePromoteRepository.updateOnsale(status, id);
    }
}